import { MotaInterface } from "@/mota";
import { UnitInfo } from "@/mota/data/MapDataUtils";
import ScrollTool from "@/mota/tools/ScrollTool";
import BuildUtils from "@/mota/utils/BuildUtils"

export default class BuildLayer extends ScrollTool<UnitInfo> implements MotaInterface {

	public build: BuildUtils;

	public ZIndex: number = 6;

	public constructor(build: BuildUtils) {
		super({
			Left: 0,
			Top: 1.2,
			Width: 4,
			Height: 11 - 1.2,
			Padding: 0.1,
			ItemWidth: 4 - 0.2 - 0.1,
			ItemHeight: 1.2,
			ItemPadding: 0.1,
			ScrollWidth: 0.1,
		});
		this.build = build;
		this.CalcSize();
	}

	public CalcSize(): void {
		const { build: { map: { unit } } } = this;
		this.List.Value = Array.from(unit);
	}

	public AppendUnit(info: UnitInfo) {
		this.CalcSize();
	}

	public DeleteUnit(info: UnitInfo) {
		this.CalcSize();
		this.SelectIndex = undefined;
	}

	public InView(): boolean {
		const { build } = this;
		const { buildState, Mota } = build;
		const { onBuild } = Mota;
		return onBuild && (buildState === "none");
	}

	public JudgeKey: MotaInterface["JudgeKey"] = (keyUtils): void => {
		if (!this.InView()) { return; }

		const { build, SelectIndex, SelectItem } = this;
		const { map } = build;

		const list = this.List.Value;
		const length = this.Length.Value;

		for (const key of keyUtils.keyHistory) {
			if (key === "Escape" && SelectIndex !== undefined) {
				this.SelectIndex = undefined;
				keyUtils.delete(key);
			}
			else if (key === "ArrowUp" && keyUtils.has("Control")) {
				if (SelectIndex !== undefined) {
					const targetIndex = SelectIndex - 1;
					if (this.Swap(SelectIndex, targetIndex)) {
						map.unit = new Set(list);
						this.SelectIndex = targetIndex;
						this.CalcSize();
						this.EnsureVisible();
						keyUtils.delete(key);
					}
				}
			}
			else if (key === "ArrowDown" && keyUtils.has("Control")) {
				if (SelectIndex !== undefined) {
					const targetIndex = SelectIndex + 1;
					if (this.Swap(SelectIndex, targetIndex)) {
						map.unit = new Set(list);
						this.SelectIndex = targetIndex;
						this.CalcSize();
						this.EnsureVisible();
						keyUtils.delete(key);
					}
				}
			}
			else if (key === "ArrowUp") {
				this.SelectLast(true);
				keyUtils.delete(key);
			}
			else if (key === "ArrowDown") {
				this.SelectNext(true);
				keyUtils.delete(key);
			} else if ((key === "Enter" || key === " ")) {
				if (SelectItem !== undefined) {
					build.select.Open(SelectItem).then(() => {
						build.buildState = "none";
					});
					build.buildState = "select";
					keyUtils.delete(key);
				}
			}
			else if ((key === "Backspace" || key === "Delete")) {
				if (SelectItem !== undefined) {
					build.DeleteUnit(SelectItem)
					keyUtils.delete(key);
				}
			}
			else if ((key === "a")) {
				build.append.Open().then(() => {
					build.buildState = "none";
				});
				build.buildState = "append";
				keyUtils.delete(key);
			}
		}
	}

	public click: MotaInterface["click"] = ([], posf) => {
		if (!this.InView()) { return; }

		const { build, SelectIndex } = this;
		const { range } = build;

		if (range !== "map") { this.SelectIndex = undefined; return; }

		const y = this.GetYByPos(posf[1]) - this.Progress;
		if (y === -1) {
			build.append.Open().then(() => {
				build.buildState = "none";
			});
			build.buildState = "append";
		} else {
			const info = this.GetItemByPos(...posf);
			if (info) {
				const list = this.List.Value;
				const index = list.indexOf(info);
				if (index === SelectIndex) {
					build.select.Open(info).then(() => {
						build.buildState = "none";
					});
					build.buildState = "select";
				} else {
					this.SelectIndex = index;
				}
			}
		}
	}

	public mousewheel: MotaInterface["mousewheel"] = (delta: number) => {
		if (!this.InView()) { return; }

		const isDown = delta > 0;
		this.Progress += isDown ? 1 : -1;
	}

	public Draw: MotaInterface["Draw"] = (draw) => {
		if (!this.InView()) { return; }

		const { _2d } = draw;
		const { Left: { Value: left }, Top: { Value: top } } = this;

		_2d.save();
		_2d.fillStyle = "#FFFFFF";
		_2d.strokeStyle = "#00FF00";
		draw.SetFont(400, 1 / 3, "Mota");
		_2d.textAlign = "left";
		_2d.textBaseline = "top";
		draw.SetLineWidth(1 / 16);

		draw.fillText("新增单位", left + 1.35, top - 0.65);

		_2d.save();
		for (const [unit, isSelect, [oX, oY, ,], [x, y, w, h]] of this.GetItemsSize()) {
			const [image, show, size, state, event] = unit;
			draw.DrawUnti([image, show, [oX, oY], state, event]);
			draw.fillText(image, oX + h, oY + 0.1);
			draw.fillText(`[${size.join(",")}]`, oX + h, oY + 0.55);
			if (isSelect) {
				draw.strokeRect(x, y, w, h);
			}
		}
		_2d.restore();

		{
			const scrollSize = this.GetScrollSize();
			if (scrollSize) {
				const [[x, y, w, h], [sx, sy, sw, sh]] = scrollSize;
				_2d.fillStyle = "#00000044";
				draw.fillRect(x - 0.05, y - 0.05, w, h);
				_2d.fillStyle = "#000";
				draw.fillRect(sx - 0.05, sy - 0.05, sw, sh);
			}
		}

		_2d.restore();
	}

}
